/* eslint-disable @typescript-eslint/no-explicit-any */
import { standardRequestAi } from "./request";

/**
 * 文件类型
 */
type FileType = 'image';

/**
 * 响应模式
 */
type ResponseMode = 'streaming' | 'blocking';

/**
 * 上传文件对象（远程 URL 方式）
 */
interface RemoteFileUpload {
    type: FileType;
    transfer_method: 'remote_url';
    url: string;
}

/**
 * 上传文件对象（本地文件方式）
 */
interface LocalFileUpload {
    type: FileType;
    transfer_method: 'local_file';
    upload_file_id: string;
}

/**
 * 文件上传联合类型
 */
type FileUpload = RemoteFileUpload | LocalFileUpload;

/**
 * 发送对话消息请求参数
 */
export interface SendChatMessageRequest {
    api_key: string;
    /** 用户输入/提问内容 */
    query: string;
    /** 允许传入 App 定义的各变量值，默认 {} */
    inputs: Record<string, any>;
    /** 响应模式：streaming 流式模式（推荐），blocking 阻塞模式 */
    response_mode: ResponseMode;
    /** 用户标识，用于定义终端用户的身份 */
    user: string;
    /** 会话 ID，需要基于之前的聊天记录继续对话时传入 */
    conversation_id?: string;
    /** 上传的文件 */
    files?: FileUpload[];
    /** 自动生成标题，默认 true */
    auto_generate_name?: boolean;

}

/**
 * 停止响应请求参数
 */
export interface StopChatMessageRequest {
    api_key: string;
    /** 任务 ID，可在流式返回 Chunk 中获取 */
    task_id: string;
    /** 用户标识，用于定义终端用户的身份 */
    user: string;
}

/**
 * 停止响应返回结果
 */
export interface StopChatMessageResponse {
    /** 固定返回 success */
    result: string;
}

/**
 * 获取建议问题请求参数
 */
export interface GetSuggestedQuestionsRequest {
    api_key: string;
    /** 消息 ID */
    message_id: string;
    /** 用户标识，由开发者定义规则，需保证用户标识在应用内唯一 */
    user: string;
}

/**
 * 获取建议问题返回结果
 */
export interface GetSuggestedQuestionsResponse {
    /** 建议问题列表 */
    data: string[];
}

/**
 * 获取会话历史消息请求参数
 */
export interface GetMessagesRequest {
    api_key: string;
    /** 会话 ID */
    conversation_id: string;
    /** 用户标识，由开发者定义规则，需保证用户标识在应用内唯一 */
    user: string;
    /** 当前页第一条聊天记录的 ID，默认 null */
    first_id?: string | null;
    /** 一次请求返回多少条聊天记录，默认 20 条 */
    limit?: number;
}

/**
 * 获取会话历史消息返回结果
 */
export interface GetMessagesResponse {
    /** 历史消息列表（倒序返回） */
    data: HistoryMessage[];
    /** 是否存在下一页 */
    has_more?: boolean;
    /** 本次返回条数（可能受系统限制） */
    limit?: number;
}

/**
 * 历史消息中的文件
 */
export interface HistoryMessageFileItem {
    /** 文件唯一 ID */
    id: string;
    /** 文件类型，image */
    type: string;
    /** 预览图片地址 */
    url: string;
    /** 文件归属方，user 或 assistant */
    belongs_to: string;
}

/**
 * Agent 思考内容（仅 Agent 模式下非空）
 */
export interface AgentThoughtItem {
    /** agent_thought ID */
    id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 在消息中的位置（从 1 开始） */
    position: number;
    /** agent 的思考内容 */
    thought: string;
    /** 工具调用的返回结果 */
    observation: string;
    /** 使用的工具列表（以 ; 分割） */
    tool: string;
    /** 工具输入（JSON 字符串） */
    tool_input: string;
    /** 创建时间戳 */
    created_at: number;
    /** 当前 agent_thought 关联的文件 ID 列表 */
    message_files?: string[];
    /** 文件 ID（当单文件时可能出现） */
    file_id?: string;
    /** 会话 ID */
    conversation_id: string;
}

/**
 * 消息反馈
 */
export interface MessageFeedback {
    /** 点赞/点踩：like/dislike */
    rating?: 'like' | 'dislike';
    /** 其他反馈字段 */
    [key: string]: any;
}

/**
 * 历史消息项
 */
export interface HistoryMessage {
    /** 消息 ID */
    id: string;
    /** 会话 ID */
    conversation_id: string;
    /** 用户输入参数 */
    inputs?: Record<string, any>;
    /** 用户输入/提问内容 */
    query?: string;
    /** 消息文件 */
    message_files?: HistoryMessageFileItem[];
    /** Agent 思考内容（仅 Agent 模式） */
    agent_thoughts?: AgentThoughtItem[];
    /** 回答消息内容 */
    answer?: string;
    /** 创建时间戳 */
    created_at: number;
    /** 反馈信息 */
    feedback?: MessageFeedback;
    /** 引用和归属分段列表 */
    retriever_resources?: RetrieverResource[];
}

/**
 * 文字转语音请求参数
 */
export interface TextToAudioRequest {
    api_key: string;
    /** Dify 生成的文本消息 ID，如果同时传 message_id 和 text，优先使用 message_id */
    message_id?: string;
    /** 语音生成内容，如果没有传 message_id 的话，则会使用这个字段的内容 */
    text?: string;
    /** 用户标识，由开发者定义规则，需保证用户标识在应用内唯一 */
    user: string;
}

/**
 * 文字转语音返回结果
 */
export interface TextToAudioResponse {
    /** 任务 ID */
    task_id?: string;
    /** 音频数据或 URL */
    audio?: string;
    /** 其他可能的响应字段 */
    [key: string]: any;
}

/**
 * 模型用量信息
 */
export interface Usage {
    /** 提示词 token 数 */
    prompt_tokens?: number;
    /** 回复 token 数 */
    completion_tokens?: number;
    /** 总 token 数 */
    total_tokens?: number;
}

/**
 * 引用和归属分段
 */
export interface RetrieverResource {
    /** 分段位置 */
    position?: number;
    /** 数据集 ID */
    dataset_id?: string;
    /** 数据集名称 */
    dataset_name?: string;
    /** 文档 ID */
    document_id?: string;
    /** 文档名称 */
    document_name?: string;
    /** 分段 ID */
    segment_id?: string;
    /** 分段内容 */
    content?: string;
    /** 分段分数 */
    score?: number;
}

/**
 * 元数据
 */
export interface Metadata {
    /** 模型用量信息 */
    usage?: Usage;
    /** 引用和归属分段列表 */
    retriever_resources?: RetrieverResource[];
}

/**
 * ChatCompletionResponse - blocking 模式响应
 */
export interface ChatCompletionResponse {
    /** 消息唯一 ID */
    message_id: string;
    /** 会话 ID */
    conversation_id: string;
    /** App 模式，固定为 chat */
    mode: string;
    /** 完整回复内容 */
    answer: string;
    /** 元数据 */
    metadata?: Metadata;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：LLM 返回文本块事件
 */
export interface MessageEvent {
    event: 'message';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 会话 ID */
    conversation_id: string;
    /** LLM 返回文本块内容 */
    answer: string;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：Agent 模式下返回文本块事件
 */
export interface AgentMessageEvent {
    event: 'agent_message';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 会话 ID */
    conversation_id: string;
    /** LLM 返回文本块内容 */
    answer: string;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：Agent 思考步骤
 */
export interface AgentThoughtEvent {
    event: 'agent_thought';
    /** agent_thought ID */
    id: string;
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** agent_thought 在消息中的位置 */
    position: number;
    /** agent 的思考内容 */
    thought: string;
    /** 工具调用的返回结果 */
    observation: string;
    /** 使用的工具列表，以 ; 分割 */
    tool: string;
    /** 工具的输入，JSON 格式的字符串 */
    tool_input: string;
    /** 创建时间戳 */
    created_at: number;
    /** 当前 agent_thought 关联的文件 ID */
    message_files?: string[];
    /** 文件 ID */
    file_id?: string;
    /** 会话 ID */
    conversation_id: string;
}

/**
 * 流式事件：文件事件
 */
export interface MessageFileEvent {
    event: 'message_file';
    /** 文件唯一 ID */
    id: string;
    /** 文件类型，目前仅为 image */
    type: string;
    /** 文件归属，user 或 assistant */
    belongs_to: string;
    /** 文件访问地址 */
    url: string;
    /** 会话 ID */
    conversation_id: string;
}

/**
 * 流式事件：消息结束事件
 */
export interface MessageEndEvent {
    event: 'message_end';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 会话 ID */
    conversation_id: string;
    /** 元数据 */
    metadata?: Metadata;
}

/**
 * 流式事件：TTS 音频流事件
 */
export interface TtsMessageEvent {
    event: 'tts_message';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 语音合成后的音频块（Base64 编码） */
    audio: string;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：TTS 音频流结束事件
 */
export interface TtsMessageEndEvent {
    event: 'tts_message_end';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 结束事件时为空字符串 */
    audio: string;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：消息内容替换事件
 */
export interface MessageReplaceEvent {
    event: 'message_replace';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** 会话 ID */
    conversation_id: string;
    /** 替换内容 */
    answer: string;
    /** 创建时间戳 */
    created_at: number;
}

/**
 * 流式事件：错误事件
 */
export interface ErrorEvent {
    event: 'error';
    /** 任务 ID */
    task_id: string;
    /** 消息唯一 ID */
    message_id: string;
    /** HTTP 状态码 */
    status: number;
    /** 错误码 */
    code: string;
    /** 错误消息 */
    message: string;
}

/**
 * 流式事件：Ping 事件
 */
export interface PingEvent {
    event: 'ping';
}

/**
 * ChunkChatCompletionResponse - streaming 模式响应（联合类型）
 */
export type ChunkChatCompletionResponse =
    | MessageEvent
    | AgentMessageEvent
    | AgentThoughtEvent
    | MessageFileEvent
    | MessageEndEvent
    | TtsMessageEvent
    | TtsMessageEndEvent
    | MessageReplaceEvent
    | ErrorEvent
    | PingEvent;

/**
 * AI 相关接口
 */
export const aiApi = {
    /**
     * 发送对话消息（阻塞模式）
     * @param params 请求参数
     * @returns 完整的响应数据
     */
    async sendChatMessage(params: SendChatMessageRequest): Promise<ChatCompletionResponse | ChunkChatCompletionResponse> {
        // 从参数中提取 api_key
        const { api_key, ...restParams } = params;
        
        const response:any = await standardRequestAi<ChatCompletionResponse | ChunkChatCompletionResponse>(
            {
                url: '/chat-messages',
                method: 'POST',
                data: restParams,
            },
            // 请求拦截器：将 api_key 设置为 Bearer token
            (config) => {
                if (config.headers) {
                    config.headers.Authorization = `Bearer ${api_key}`;
                }
                return config;
            }
        );
        return response;
    },

    /**
     * 获取会话历史消息（滚动加载，倒序返回）
     * @param params 请求参数
     * @returns 历史消息列表
     */
    async getMessages(params: GetMessagesRequest): Promise<GetMessagesResponse> {
        const { api_key, ...queryParams } = params;
        const response:any = await standardRequestAi<GetMessagesResponse>(
            {
                url: '/messages',
                method: 'GET',
                params: queryParams,
            },
            (config) => {
                if (config.headers) {
                    config.headers.Authorization = `Bearer ${api_key}`;
                }
                return config;
            }
        );
        return response;
    },

    /**
     * 发送对话消息（流式模式）- 使用 fetch 实现 SSE
     * @param params 请求参数
     * @param onMessage 接收到消息事件时的回调
     * @param onError 发生错误时的回调
     * @param onEnd 流结束时的回调
     */
    async sendChatMessageStream(
        params: SendChatMessageRequest,
        onMessage?: (data: ChunkChatCompletionResponse) => void,
        onError?: (error: Error) => void,
        onEnd?: () => void
    ): Promise<void> {
        const { api_key, ...restParams } = params;
        const baseURL = import.meta.env.VITE_AI_DIALOG_URL;
        
        try {
            const response = await fetch(`${baseURL}/chat-messages`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${api_key}`,
                },
                body: JSON.stringify(restParams),
            });

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const reader = response.body?.getReader();
            const decoder = new TextDecoder();

            if (!reader) {
                throw new Error('Response body is null');
            }

            let buffer = '';

            while (true) {
                const { done, value } = await reader.read();
                
                if (done) {
                    onEnd?.();
                    break;
                }

                // 解码数据块
                buffer += decoder.decode(value, { stream: true });
                
                // 按行分割
                const lines = buffer.split('\n');
                // 保留最后一个不完整的行
                buffer = lines.pop() || '';

                for (const line of lines) {
                    const trimmedLine = line.trim();
                    
                    // 跳过空行和注释
                    if (!trimmedLine || trimmedLine.startsWith(':')) {
                        continue;
                    }

                    // 解析 SSE 数据：格式为 "data: {...}"
                    if (trimmedLine.startsWith('data: ')) {
                        const jsonStr = trimmedLine.slice(6); // 移除 "data: " 前缀
                        
                        try {
                            const eventData = JSON.parse(jsonStr) as ChunkChatCompletionResponse;
                            onMessage?.(eventData);
                        } catch (e) {
                            console.error('JSON 解析错误:', e, jsonStr);
                        }
                    }
                }
            }
        } catch (error) {
            console.error('流式请求错误:', error);
            const err = error instanceof Error ? error : new Error(String(error));
            onError?.(err);
        }
    },

    /**
     * 停止响应（仅支持流式模式）
     * @param params 请求参数
     * @returns 停止结果
     */
    async stopChatMessage(params: StopChatMessageRequest): Promise<StopChatMessageResponse> {
        // 从参数中提取 api_key 和 task_id
        const { api_key, task_id, user } = params;
        
        const response:any = await standardRequestAi<StopChatMessageResponse>(
            {
                url: `/chat-messages/${task_id}/stop`,
                method: 'POST',
                data: { user },
            },
            // 请求拦截器：将 api_key 设置为 Bearer token
            (config) => {
                if (config.headers) {
                    config.headers.Authorization = `Bearer ${api_key}`;
                }
                return config;
            }
        );
        return response;
    },

    /**
     * 获取下一轮建议问题列表
     * @param params 请求参数
     * @returns 建议问题列表
     */
    async getSuggestedQuestions(params: GetSuggestedQuestionsRequest): Promise<GetSuggestedQuestionsResponse> {
        // 从参数中提取 api_key、message_id 和 user
        const { api_key, message_id, user } = params;
        
        const response:any = await standardRequestAi<GetSuggestedQuestionsResponse>(
            {
                url: `/messages/${message_id}/suggested`,
                method: 'GET',
                params: { user },
            },
            // 请求拦截器：将 api_key 设置为 Bearer token
            (config) => {
                if (config.headers) {
                    config.headers.Authorization = `Bearer ${api_key}`;
                }
                return config;
            }
        );
        return response;
    },

    /**
     * 文字转语音
     * @param params 请求参数
     * @returns 语音数据 Blob
     */
    async textToAudio(params: TextToAudioRequest): Promise<Blob> {
        // 从参数中提取 api_key
        const { api_key, ...restParams } = params;
        
        const response:any = await standardRequestAi<Blob>(
            {
                url: '/text-to-audio',
                method: 'POST',
                data: restParams,
                responseType: 'blob', // 设置响应类型为 blob 以接收二进制数据
            },
            // 请求拦截器：将 api_key 设置为 Bearer token
            (config) => {
                if (config.headers) {
                    config.headers.Authorization = `Bearer ${api_key}`;
                }
                return config;
            }
        );
        return response;
    },
};
